﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
using The_Quest.Entities.Abstract;
using The_Quest.Entities.Enemies;
using The_Quest.Entities.Potions;
using The_Quest.Entities.Weapons;
using The_Quest.Enums;
using The_Quest.Entities.Concrete;

namespace The_Quest
{
    class Game
    {
        private Player player;//The game keeps a private Player object. The form will only interact with this through methods on Game, rather than directly.
        private int _level = 0;
        private Rectangle _boundaries;//The Rectangle object has Top, Bottom, Left, and Right fields, and works perfectly for the overall game area.


        public IEnumerable<Enemy> Enemies { get; private set; }
        public Weapon WeaponInRoom { get; private set; }
        public Point PlayerLocation { get { return player.Location; } }
        public int PlayerHitPoints { get { return player.HitPoints; } }
        public IEnumerable<string> PlayerWeapons { get { return player.Weapons; } }
        public int Level { get { return _level; } }
        public Rectangle Boundaries { get { return _boundaries; } }



        public Game(Rectangle boundaries) //Game starts out with a bounding box for the dungeon, and creates a new Player object in the dungeon.
        {
            this._boundaries = boundaries;
            player = new Player(this, new Point(boundaries.Left+10, boundaries.Top+100));
        }

        public void Move(Direction direction, Random random)//Movement is simple: move the player in the direction the form gives us, and move each enemy in a random direction.
        {
            player.Move(direction);
            foreach (Enemy enemy in Enemies)
                enemy.Move(random);
        }

        public void Equip(string weaponName)
        {
            player.Equip(weaponName);
        }

        public bool CheckPlayerInventory(string weaponName)
        {
            return player.Weapons.Contains(weaponName);
        }

        public void HitPlayer(int maxDamage, Random random)
        {
            player.Hit(maxDamage, random);
        }

        public void IncreasePlayerHealth(int health, Random random)
        {
            player.IncreaseHealth(health, random);
        }

        public void Attack(Direction direction, Random random)//Attack() is almost exactly like Move(). The player attacks, and the enemies all get a turn to move.
        {
            player.Attack(direction, random);

            foreach (Enemy enemy in Enemies)
                enemy.Move(random);
        }

        public void NewLevel(Random random)
        {
            _level++;
            switch (_level)
            {
                case 1:
                    Enemies = new List<Enemy>() 
                    { 
                        new Bat(this, GetRandomLocation(random))
                    };

                    WeaponInRoom = new Sword(this, GetRandomLocation(random));
                    break;


                case 2:
                    Enemies = new List<Enemy>()
                    {
                        new Ghost(this, GetRandomLocation(random))
                    };

                    WeaponInRoom = new BluePotion(this, GetRandomLocation(random));
                    break;



                case 3:
                    Enemies = new List<Enemy>()
                    {
                        new Ghoul(this, GetRandomLocation(random))
                    };

                    WeaponInRoom = new Bow(this, GetRandomLocation(random));
                    break;



                case 4:
                    Enemies = new List<Enemy>()
                    {
                        new Bat(this, GetRandomLocation(random)),
                        new Ghost(this, GetRandomLocation(random))
                    };
                    // WeaponInRoom=Bow, if not picked up on 3; otherwise, blue potion.
                    if (!CheckPlayerInventory("Bow"))
                    {
                        WeaponInRoom = new Bow(this, GetRandomLocation(random));
                    }
                    else
                    {
                        WeaponInRoom = new BluePotion(this, GetRandomLocation(random));
                    }
                    break;


                case 5:
                    Enemies = new List<Enemy>()
                    {
                        new Bat(this, GetRandomLocation(random)),
                        new Ghoul(this, GetRandomLocation(random))
                    };
                    WeaponInRoom = new RedPotion(this, GetRandomLocation(random));
                    break;


                case 6:
                    Enemies = new List<Enemy>()
                    {
                        new Ghost(this, GetRandomLocation(random)),
                        new Ghoul(this, GetRandomLocation(random))
                    };
                    WeaponInRoom = new Mace(this, GetRandomLocation(random));
                    break;


                case 7:
                    Enemies = new List<Enemy>()
                    {
                        new Bat(this, GetRandomLocation(random)),
                        new Ghost(this, GetRandomLocation(random)),
                        new Ghoul(this,GetRandomLocation(random))
                    };
                    // WeaponInRoom=Mace, if not picked up on 6; otherwise, red potion.
                    if (!CheckPlayerInventory("Mace"))
                    {
                        WeaponInRoom = new Mace(this, GetRandomLocation(random));
                    }
                    else
                    {
                        WeaponInRoom = new RedPotion(this, GetRandomLocation(random));
                    }
                    break;


                case 8:
                    MessageBox.Show(@"Congratulations!"+Environment.NewLine+@"You are Dungeon Legend now!");
                    Application.Exit();
                    break;

            }
        }

        private Point GetRandomLocation(Random random) //GetRandomLocation() will come in handy in the NewLevel() method, which will use it to determine where to place enemies and weapons.
        {
            //This is just a math trick to get a random location within the rectangle that represents the dungeon area.
            return new Point(_boundaries.Left + random.Next(_boundaries.Right / 10 - _boundaries.Left / 10) * 10, _boundaries.Top + random.Next(_boundaries.Bottom / 10 - _boundaries.Top / 10) * 10);
        }
    }
}
